package ch.ethz.group3.myalbum.client;

import java.util.ArrayList;
import java.util.Collection;

import ch.ethz.group3.myalbum.client.utils.Global;
import ch.ethz.group3.myalbum.client.utils.Notifier;
import ch.ethz.group3.myalbum.shared.ImageModel;
import ch.ethz.group3.myalbum.shared.InvalidFlickrTokenException;

import com.google.gwt.core.client.GWT;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.event.MarkerClickHandler;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.geom.LatLngBounds;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.BkgndRepeat;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tile.TileRecord;
import com.smartgwt.client.widgets.tile.events.RecordClickEvent;
import com.smartgwt.client.widgets.tile.events.RecordClickHandler;
import com.smartgwt.client.widgets.tile.events.RecordDoubleClickEvent;
import com.smartgwt.client.widgets.tile.events.RecordDoubleClickHandler;
import com.smartgwt.client.widgets.viewer.DetailFormatter;
import com.smartgwt.client.widgets.viewer.DetailViewerField;

public class ImageGridPanel extends VLayout {

	private final ImageTileGrid tileGrid;
	private final ImageDataSource ds;
	private final PictureServiceAsync pictureService;
	private MapWidget map;
	private ArrayList<Marker> previousMarker;

	public ImageGridPanel() {
		this.tileGrid = new ImageTileGrid();
		this.previousMarker = new ArrayList<Marker>();
		this.pictureService = GWT.create(PictureService.class);
		setAlign(Alignment.CENTER);
		setLayoutAlign(Alignment.CENTER);
		setLayoutAlign(VerticalAlignment.CENTER);
		setLayoutAlign(Alignment.CENTER);
		tileGrid.setLayoutAlign(Alignment.CENTER);
		tileGrid.setLayoutAlign(VerticalAlignment.CENTER);
		tileGrid.setAnimateTileChange(true);  
		tileGrid.setBackgroundImage("fgf.png");
		tileGrid.setBackgroundRepeat(BkgndRepeat.NO_REPEAT);
		tileGrid.setBackgroundPosition("center");
		
		tileGrid.setCanDrag(true);
		tileGrid.setCanReorderTiles(true);
		tileGrid.setSmoothFade(true);
		
		tileGrid.addRecordClickHandler(new RecordClickHandler() {
			
			@Override
			public void onRecordClick(RecordClickEvent event) {
				String location = event.getRecord().getAttribute("geoLocation");
				String name = event.getRecord().getAttribute("name");
				if(location != null && !location.equals("")){
					String[] split0 = location.split(" ");
					LatLng loc = LatLng.newInstance(Double.parseDouble(split0[0]), Double.parseDouble(split0[1]));
					map.setCenter(loc,17);
					map.getInfoWindow().open(loc, new InfoWindowContent(name));
				}
			}
		});
		
	    DetailViewerField pictureField = new DetailViewerField("thumbnail");  
	    pictureField.setType("image");
	    
	    DetailViewerField nameField = new DetailViewerField("name");  
	    nameField.setCellStyle("cellname");  
	    
	    DetailViewerField geolocField = new DetailViewerField("geoLocation");  
	    geolocField.setDetailFormatter(new DetailFormatter() {  
	            public String format(Object value, Record record, DetailViewerField field) {  
	                return "Location: " + ((value != null) ? "<span style='color: green'>Yes</span>" : "<span style='color: red'>No</span>");  
	            }  
	    });
	    
	    DetailViewerField commentCountField = new DetailViewerField("commentCount");  
	    commentCountField.setDetailFormatter(new DetailFormatter() {  
            public String format(Object value, Record record, DetailViewerField field) {  
                return "Comments: " + (((Integer) value > 0) ? "<span style='color: green'>"+value+"</span>" : "<span style='color: red'>0</span>");  
            }  
	    });
	    
	    tileGrid.setFields(pictureField, nameField, geolocField, commentCountField);
		ds = ImageDataSource.getInstance();
		tileGrid.setDataSource(ds);

		addMember(tileGrid);
		
		tileGrid.addRecordDoubleClickHandler(new RecordDoubleClickHandler() {
			
			@Override
			public void onRecordDoubleClick(RecordDoubleClickEvent event) {
				Record rec = event.getRecord();
				if (rec instanceof ImageTileRecord) {
					ImageTileRecord image = (ImageTileRecord)rec;
					Notifier.showImage(image);
				}
			}
		});

	}
	
	public void setMap(MapWidget map){
		this.map = map;
	}

	public void loadGroupImages(String groupId) {
		final LoadingWindow loadingWindow = new LoadingWindow();
		loadingWindow.show();
		
		pictureService.getAlbum(groupId, 30, 0, Global.accessToken,
				new AsyncCallback<Collection<ImageModel>>() {

					@Override
					public void onSuccess(Collection<ImageModel> images) {
						map.clearOverlays();
						previousMarker.clear();
						if(images.size()>0){
							tileGrid.setBackgroundImage("fgf_fade.png");
						}
						else{
							tileGrid.setBackgroundImage("fgf.png");
						}
						tileGrid.setData(new TileRecord[0]);
						tileGrid.fetchData();
						ds.setTestData(new ImageTileRecord[0]);
						for (final ImageModel image : images) {
							ds.addData(image.getRecord());
							if(map!=null && image.getGeoLocation().getLatitude()!=0 && image.getGeoLocation().getLongitude()!=0){								
								final LatLng location = LatLng.newInstance(image.getGeoLocation().getLatitude(), image.getGeoLocation().getLongitude());
								Marker m = new Marker(location);
								previousMarker.add(m);
								
								m.addMarkerClickHandler(new MarkerClickHandler() {
									
									@Override
									public void onClick(MarkerClickEvent event) {
										map.getInfoWindow().open(location, new InfoWindowContent(image.getName()));
										map.setCenter(location, 17);
									}
								});
								
								map.addOverlay(m);
							}
						}
						loadingWindow.destroy();

						LatLngBounds bounds = LatLngBounds.newInstance();
						for(Marker m : previousMarker){
							bounds.extend(m.getLatLng());
						}
						
						map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds)==0?0:map.getBoundsZoomLevel(bounds)-1);
					}

					@Override
					public void onFailure(Throwable caught) {
						loadingWindow.destroy();
						if (caught instanceof InvalidFlickrTokenException) {
							InvalidFlickrTokenException e = (InvalidFlickrTokenException) caught;
							Notifier.notify(e.getAuthorization());
						}
					}
				});
		}
}
